﻿#region usings
using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using AR.Entities;
using AR.ViewModels.Commands;
using System.Collections.ObjectModel;
using AR.Model;
using System.ServiceModel.DomainServices.Client;
using AR.Web;
using AR.CustomEntities;
using GalaSoft.MvvmLight.Command;
using AR.Views.Candidat;
using AR.ViewModel.Candidat;
using System.Linq;
using AR.Web.Services;
using System.Runtime.InteropServices.Automation;
using System.IO;

#endregion
//AR
namespace AR.ViewModels
{
    public class ListeCandidatViewModel : ViewModelBase
    {
        #region fields
        private Visibility _visibilityContextMenu;
        public Visibility VisibilityContextMenu
        {

            get { return _visibilityContextMenu; }
            set
            {
                _visibilityContextMenu = value;
                OnPropertyChanged("VisibilityContextMenu");
            }
        }
        private CANDIDAT _selectedCandidat;
        public CANDIDAT SelectedCandidat
        {

            get { return _selectedCandidat; }
            set
            {
                _selectedCandidat = value;
                OnPropertyChanged("SelectedCandidat");
            }
        }
        private Visibility _canshowEntretien;
        public Visibility CanshowEntretien
        {

            get { return _canshowEntretien; }
            set
            {
                _canshowEntretien = value;
                OnPropertyChanged("CanshowEntretien");
            }
        }
        private Visibility _canaddCandidat;
        public Visibility CanaddCandidat
        {

            get { return _canaddCandidat; }
            set
            {
                _canaddCandidat = value;
                OnPropertyChanged("CanaddCandidat");
            }
        }
        public ObservableCollection<NIVEAU_EXPERIENCE> _niveauxExperience;
        public ObservableCollection<NIVEAU_EXPERIENCE> NiveauxExperience
        {

            get { return _niveauxExperience; }
            set
            {
                _niveauxExperience = value;
                OnPropertyChanged("NiveauxExperience");
            }
        }
        public ObservableCollection<NIVEAU_ETUDE> _niveauxEtudes;
        public ObservableCollection<NIVEAU_ETUDE> NiveauxEtudes
        {


            get { return _niveauxEtudes; }
            set
            {
                _niveauxEtudes = value;
                OnPropertyChanged("NiveauxEtudes");
            }
        }
        private ObservableCollection<PRACTICE> _practices;
        public ObservableCollection<PRACTICE> Practices
        {
            get { return _practices; }
            set
            {
                _practices = value;
                OnPropertyChanged("Practices");
            }
        }
        private CustomCandidatEntretienEntity _candidat;
        public CustomCandidatEntretienEntity Candidat
        {
            get
            {
                return _candidat;
            }
            set
            {
                _candidat = value;
            }
        }
        private readonly CandidatModel model;
        private ObservableCollection<CANDIDAT> _candidatsresult;
        public ObservableCollection<CANDIDAT> CandidatsResult
        {
            get
            {
                return _candidatsresult;
            }
            set
            {
                if (value != _candidatsresult)
                {
                    _candidatsresult = value;
                    OnPropertyChanged("CandidatsResult");
                }
            }
        }
        private ObservableCollection<CustomCandidatEntretienEntity> _customCandidatsresult;
        public ObservableCollection<CustomCandidatEntretienEntity> CustomCandidatsResult
        {
            get
            {
                return _customCandidatsresult;
            }
            set
            {
                if (value != _customCandidatsresult)
                {
                    _customCandidatsresult = value;
                    OnPropertyChanged("CustomCandidatsResult");
                }
            }
        }
        private SearchCandidatCritaria _criteria;
        public SearchCandidatCritaria Criteria
        {
            get { return _criteria; }
            set
            {
                _criteria = value;
                OnPropertyChanged("Criteria");
            }
        }
        private EntretienOraleContext oralecontext { get; set; }
        private EntretienTechniqueContext techniquecontext { get; set; }
        private ObservableCollection<TAG> _Tags;
        public ObservableCollection<TAG> Tags
        {
            get { return _Tags; }
            set
            {
                if (_Tags != value)
                {
                    _Tags = value;
                    OnPropertyChanged("Tags");
                }
            }
        }
        private string _SearchTagsTxt;
        public string SearchTagsTxt
        {
            get { return _SearchTagsTxt; }
            set
            {
                if (_SearchTagsTxt != value)
                {
                    _SearchTagsTxt = value;
                    OnPropertyChanged("SearchTagsTxt");
                }
            }
        }
        private ObservableCollection<TAG> _TagsTrouves;
        public ObservableCollection<TAG> TagsTrouves
        {
            get { return _TagsTrouves; }
            set
            {
                if (_TagsTrouves != value)
                {
                    _TagsTrouves = value;
                    OnPropertyChanged("TagsTrouves");
                }
            }
        }
        private ObservableCollection<TAG> _SelectedTags;
        public ObservableCollection<TAG> SelectedTags
        {
            get { return _SelectedTags; }
            set
            {
                if (_SelectedTags != value)
                {
                    _SelectedTags = value;
                    OnPropertyChanged("SelectedTags");
                }
            }
        }
        #endregion

        #region Constructeurs
        public ListeCandidatViewModel()
        {
            //    MessageBox.Show(Application.Current.HasElevatedPermissions.ToString());
            if (WebContext.Current.User.IsAuthenticated)
            {
                model = new CandidatModel();
                InitViewModel();
            }
            else
            {
                ((MainPage)(Application.Current.RootVisual)).ContentFrame.Navigate(new Uri("/LoginPage", UriKind.Relative));
            }
        }
        private void InitViewModel()
        {
            oralecontext = new EntretienOraleContext();
            techniquecontext = new EntretienTechniqueContext();
            PRACTICE practice = new PRACTICE();
            NIVEAU_ETUDE etude = new NIVEAU_ETUDE();
            NIVEAU_EXPERIENCE exp = new NIVEAU_EXPERIENCE();
            exp.ID_EXPERIENCE = -1;
            exp.INTITULE = "Sélectionnez...";
            etude.ID_ETUDE = -1;
            etude.INTITULE = "Sélectionnez...";
            practice.ID_PRACTICE = -1;
            practice.PRACTICE1 = "Sélectionnez...";
            //  practice.set = EntityState.New;
            Practices = new ObservableCollection<PRACTICE>();
            Practices.Add(practice);
            NiveauxEtudes = new ObservableCollection<NIVEAU_ETUDE>();
            NiveauxEtudes.Add(etude);
            NiveauxExperience = new ObservableCollection<NIVEAU_EXPERIENCE>();
            NiveauxExperience.Add(exp);
            CandidatsResult = new ObservableCollection<CANDIDAT>();
            CustomCandidatsResult = new ObservableCollection<CustomCandidatEntretienEntity>();
            Tags = new ObservableCollection<TAG>();
            TagsTrouves = new ObservableCollection<TAG>();
            SearchTagsTxt = "";
            SelectedTags = new ObservableCollection<TAG>();
            model.GetPractices().EntityAdded += OnEntityAdded;
            model.GetNiveauEtudes().EntityAdded += OnEntityAdded;
            model.GetNiveauExperience().EntityAdded += OnEntityAdded;
            model.GetTags().EntityAdded += OnEntityAdded;
            checkRole();
            initCandidat();
            searchCandidat();
        }
        #endregion

        #region Entity Added
        private void OnEntityAdded(object sender,
                      EntityCollectionChangedEventArgs<PRACTICE> entityCollectionChangedEventArgs)
        {
            Practices.Add(entityCollectionChangedEventArgs.Entity);



        }
        private void OnEntityAdded(object sender,
                     EntityCollectionChangedEventArgs<NIVEAU_ETUDE> entityCollectionChangedEventArgs)
        {
            NiveauxEtudes.Add(entityCollectionChangedEventArgs.Entity);
        }
        private void OnEntityAdded(object sender,
                     EntityCollectionChangedEventArgs<NIVEAU_EXPERIENCE> entityCollectionChangedEventArgs)
        {
            NiveauxExperience.Add(entityCollectionChangedEventArgs.Entity);
        }
        private void OnEntityRemoved(object sender,
                                EntityCollectionChangedEventArgs<CANDIDAT> entityCollectionChangedEventArgs)
        {
            if (CustomCandidatsResult.Where(_ => _.candidat == entityCollectionChangedEventArgs.Entity).Count() != 0)
                CustomCandidatsResult.Remove(CustomCandidatsResult.Where(_ => _.candidat == entityCollectionChangedEventArgs.Entity).Single());
        }
        private void OnEntityAdded(object sender,
                                EntityCollectionChangedEventArgs<CANDIDAT> entityCollectionChangedEventArgs)
        {
            if (CustomCandidatsResult.Where(_ => _.candidat == entityCollectionChangedEventArgs.Entity).Count() == 0)
            {
                CustomCandidatEntretienEntity CustomCandidat = new CustomCandidatEntretienEntity();
                CustomCandidat.candidat = entityCollectionChangedEventArgs.Entity;
                CustomCandidatsResult.Add(CompleteCandidatEntity(CustomCandidat));
            }
        }

        private void OnEntityAdded(object sender, EntityCollectionChangedEventArgs<TAG> e)
        {
            Tags.Add(e.Entity);
        }

        #endregion

        #region ViewModelMethods
        public CustomCandidatEntretienEntity CompleteCandidatEntity(CustomCandidatEntretienEntity entity)
        {
            CustomCandidatEntretienEntity candidatentity = entity;


            if (entity.candidat.ETAT_ENTRETIEN_ORALE == 1)
            {
                entity.entretienOraleContent = "Résultat Entretien Orale";
                entity.entretienOraleEnabled = true;
                entity.entretienOraleUri = new Uri("/ResultatEntretienOral/" + entity.candidat.ID_CANDIDAT, UriKind.Relative);
            }
            else if (entity.candidat.ETAT_ENTRETIEN_ORALE != 1 && (WebContext.Current.User.IsInRole("Admin")) || (WebContext.Current.User.IsInRole("SolutionManager")))
            {
                entity.entretienOraleContent = "Passer l'entretien Orale";
                entity.entretienOraleEnabled = true;
                // ResultatEntretienTechniqueViewModel.idcandidat = entity.candidat.ID_CANDIDAT;
                entity.entretienOraleUri = new Uri("/EntretienOrale2/" + entity.candidat.ID_CANDIDAT, UriKind.Relative);
            }
            else
            {
                entity.entretienOraleContent = "Entretien Orale non passé";
                entity.entretienOraleEnabled = false;
            }


            if (entity.candidat.ETAT_ENTRETIEN_ECRIT == 1)
            {
                entity.entretienEcritContent = "Résultat Test";
                entity.entretienEcritEnabled = true;
                entity.entretienEcritUri = new Uri("/ResultatEntretienTechnique/" + entity.candidat.ID_CANDIDAT, UriKind.Relative);
            }
            else
            {
                entity.entretienEcritContent = "Non passé";
                entity.entretienEcritEnabled = false;
                //   entity.entretienOraleUri = new Uri("/ResultatEntretienOral/" + entity.candidat.ID_CANDIDAT, UriKind.Relative);
            }

            return entity;
        }
        private void checkRole()
        {
            if (WebContext.Current.User.IsInRole("Admin") || WebContext.Current.User.IsInRole("PracticeManager") || WebContext.Current.User.IsInRole("WorkforceManager"))
            {
                CanaddCandidat = Visibility.Visible;
            }
            else
            {
                CanaddCandidat = Visibility.Collapsed;
            }
            if (WebContext.Current.User.IsInRole("Admin") || WebContext.Current.User.IsInRole("SolutionManager"))
            {
                CanshowEntretien = Visibility.Visible;
            }
            else
            {
                CanshowEntretien = Visibility.Collapsed;
            }
        }
        #endregion

        #region commands
        public ICommand SearchCandidatCommand
        {
            get
            {
                return new SearchCandidat(this);
            }
        }
        public ICommand SearchCandidatCommand2
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.searchCandidat();
                });
            }
        }
        public ICommand ParcourirCommmand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.ParcourirFichier();
                });
            }
        }
        public ICommand HistoriqueCandidatCommand
        {
            get
            {
                return new RelayCommand<object>((obj) =>
                {
                    this.OpenHistory(obj);
                });
            }
        }
        public ICommand ExportCandidatsCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.ExportCandidats();
                });
            }
        }


        public ICommand CodeTestCommand
        {
            get
            {
                return new RelayCommand<object>((obj) =>
                {

                    this.Getcodetest(obj);

                });
            }
        }
        public ICommand InitialiserCommand
        {
            get
            {
                return new InitCandidat(this);
            }
        }
        public ICommand DetailsCommand
        {
            get
            {

                return new RelayCommand<object>((obj) =>
                {
                    this.Opendetails(obj);

                });
            }
        }
        public ICommand RechercheTagsCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.RechercheTags();
                });
            }
        }
        public ICommand AjoutThemeTestCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.AjoutThemeTest();

                });
            }
        }

        public ICommand SupressionTagCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.SupressionTag();

                });
            }
        }

        #endregion

        #region Commands Methods
        public void searchCandidat()
        {
            Criteria.IdTags = SelectedTags.Select(t => t.ID_TAG).ToList();
            model.FindCandidat(Criteria).EntityAdded += OnEntityAdded;
            model.FindCandidat(Criteria).EntityRemoved += OnEntityRemoved;
        }
        public void initCandidat()
        {
            Criteria = new SearchCandidatCritaria();
            Criteria.ID_PRACTICE = Practices[0].ID_PRACTICE;
            Criteria.ID_ETUDES = NiveauxEtudes[0].ID_ETUDE;
            Criteria.ID_EXPERIENCE = NiveauxExperience[0].ID_EXPERIENCE;
            Criteria.IdTags = SelectedTags.Select(st => st.ID_TAG).ToList();
            SelectedTags = new ObservableCollection<TAG>();
            SearchTagsTxt = "";
            TagsTrouves = new ObservableCollection<TAG>();
            //  Criteria.DateNaissance = DateTime.Now.AddYears(-20);            
        }
        public void Opendetails(object parameter)
        {
            Candidat = (CustomCandidatEntretienEntity)parameter;
            //string x = Candidat.EMAIL;
            if (WebContext.Current.User.IsInRole("SolutionManager"))
            {
                InformationsCandidat infos = new InformationsCandidat(Candidat.candidat);
                infos.txt_email.Text = Candidat.candidat.EMAIL;
                infos.Show();
            }
            else
            {
                Dictionary<string, string> parameters = new Dictionary<string, string>();
                parameters.Add("id", Candidat.candidat.ID_CANDIDAT.ToString());

                //NavigationService.Navigate2("/CreationCandidat", parameters);
                NavigationService.Navigate("/CreationCandidat/" + Candidat.candidat.ID_CANDIDAT);
                // CreationCandidatViewModel.candidatparam = Candidat.candidat;
            }

        }
        private void ParcourirFichier()
        {
            try
            {



                OpenFileDialog OFD = new OpenFileDialog();
                // OFD.Filter = "Fichiers CSV (*.csv)|*.csv";
                OFD.Filter = "Fichiers Excel (*.xlsx)|*.xlsx";
                OFD.FilterIndex = 1;
                OFD.Multiselect = false;



                bool? userClickedOk = OFD.ShowDialog();
                if (userClickedOk == true)
                {
                    (Application.Current.RootVisual as BusyIndicator).IsBusy = true;
                    string file_path = OFD.File.Name;
                    string fileExtension = OFD.File.Extension;

                    // appel methode pour lire les données à partir d'un fichier xlsx
                   // readXLSXdata(OFD.File.OpenRead());
                    if (OFD.File.Length < 4194304)
                    {
                        List<string[]> parsedLines = ParseCsvFile(OFD.File.OpenRead());
                        if (ValidateLines(parsedLines))
                        {

                            MapCSVCandidats(parsedLines);
                            (Application.Current.RootVisual as BusyIndicator).IsBusy = false;
                        }
                        else
                        {
                            MessageBox.Show("erreur lors du conversion de fichier vérifier que les données sont valides");
                            (Application.Current.RootVisual as BusyIndicator).IsBusy = false;
                        }
                    }
                    else
                    {
                        (Application.Current.RootVisual as BusyIndicator).IsBusy = false;
                        // taille maximal depassé 
                    }
                }
            }
            catch (IOException)
            {

                MessageBox.Show("Vous devez fermer le fichier avant de le télécharger");
            }
        }
        private void ExportCandidats()
        {
            dynamic excelApp;
            excelApp = AutomationFactory.CreateObject("Excel.Application");
            excelApp.Visible = true;
            dynamic workbook = excelApp.workbooks;
            workbook.Add();
            dynamic sheet = excelApp.ActiveSheet;
            dynamic cell = null;

            sheet.Cells[1, 1].Value = "Nom";
            sheet.Cells[1, 2].Value = "Prénom";
            sheet.Cells[1, 3].Value = "Date de naissance";
            sheet.Cells[1, 4].Value = "Niveau Expérience";
            sheet.Cells[1, 5].Value = "Niveau Etudes";
            sheet.Cells[1, 6].Value = "Email";
            sheet.Cells[1, 7].Value = "Téléphone";
            sheet.Cells[1, 8].Value = "Salaire Actuel";
            sheet.Cells[1, 9].Value = "Salaire Demandé";
            sheet.Cells[1, 10].Value = "Préavis";
            sheet.Cells[1, 11].Value = "Statut";
            sheet.Cells[1, 12].Value = "Date Test Technique";


            int index = 2;
            foreach (CustomCandidatEntretienEntity cnd in CustomCandidatsResult)
            {
                sheet.Cells[index, 1].Value = cnd.candidat.NOM;
                sheet.Cells[index, 2].Value = cnd.candidat.PRENOM;
                sheet.Cells[index, 3].Value = cnd.candidat.DATENAISSANCE;
                sheet.Cells[index, 4].Value = cnd.candidat.NIVEAU_EXPERIENCE.INTITULE;
                sheet.Cells[index, 5].Value = cnd.candidat.NIVEAU_ETUDE.INTITULE;
                sheet.Cells[index, 6].Value = cnd.candidat.EMAIL;
                sheet.Cells[index, 7].Value = cnd.candidat.TEL;
                sheet.Cells[index, 8].Value = cnd.candidat.SALAIRE_ACTUELLE;
                sheet.Cells[index, 9].Value = cnd.candidat.SALAIRE_DEMANDE;
                sheet.Cells[index, 10].Value = cnd.candidat.PREAVIS;
                sheet.Cells[index, 11].Value = cnd.candidat.STATUT_CANDIDAT.INTITULE;
                sheet.Cells[index, 12].Value = cnd.candidat.DATE_ENTRETIEN_TECHNIQUE.ToString();

                index++;
            }
        }
        private void OpenHistory(object obj)
        {
            if (SelectedCandidat != null)
            {
                HistoriqueCandidatView histo = new HistoriqueCandidatView(SelectedCandidat.ID_CANDIDAT);
                histo.Show();
            }
        }
        private void RechercheTags()
        {
            TagsTrouves.Clear();
            foreach (TAG item in Tags.Where(t => t.NOM.ToUpper().Contains(SearchTagsTxt.ToUpper())))
            {
                if (!SelectedTags.Contains(item))
                    TagsTrouves.Add(item);
            }
        }
        private void Getcodetest(object obj)
        {
            if (SelectedCandidat != null)
                Clipboard.SetText(SelectedCandidat.CODE_TEST);
        }


        private void AjoutThemeTest()
        {
        }
        private void SupressionTag()
        {
        }

        #endregion
        #region Fonctions

        //convert strea
        public static void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[16 * 1024];
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                output.Write(buffer, 0, read);
            }
        }
        public List<string[]> ParseCsvFile(FileStream File)
        {
            List<string[]> parsedLines = new List<string[]>();
            // Ouverture du fichier CSV
            //AGA bug 4901 mauvais choix d'encodage pour le reader. utilisé la code page windows pour l'europe de l'ouest : 1252
            StreamReader readFile = new StreamReader(File, true);
            // StreamReader readFile = new StreamReader(File, Encoding.GetEncoding("1252"));
            string line;
            string[] row;

            // On boucle sur toutes les lignes
            while ((line = readFile.ReadLine()) != null)
            {
                row = line.Split(';');
                parsedLines.Add(row);
            }

            return parsedLines;
        }
        public bool ValidateLines(List<string[]> parsedLines)
        {
            int outinteger;
            DateTime outDatetime;
            bool isvalid = true;
            //si le nombre de colonnes est respecter
            if (parsedLines.ElementAt(0).Count() != 11)
            {
                isvalid = false;
                return false;
            }
            else
            {
                parsedLines.RemoveAt(0);
                foreach (var line in parsedLines)
                {
                    if (!(int.TryParse(line[5], out outinteger)) || !(int.TryParse(line[6], out outinteger)) || !(int.TryParse(line[7], out outinteger)))
                    {
                        isvalid = false;
                    }
                    else if (!(DateTime.TryParse(line[10], out outDatetime)))
                    {
                        isvalid = false;
                    }


                }
                return isvalid;
            }
        }
        public void MapCSVCandidats(List<string[]> parsedLines)
        {
            ObservableCollection<CSVCandidat> ListCandidatsCsv = new ObservableCollection<CSVCandidat>(); ;
            CSVCandidat candidat;
            int i = 1;
            foreach (var line in parsedLines)
            {

                candidat = new CSVCandidat()
                {
                    NumeroLigne = i,
                    Source = line[0],
                    Nom = line[1],
                    Prenom = line[2],
                    NiveauEtudes = line[3],
                    NiveauExp = line[4],
                    Salaire_Actuelle = int.Parse(line[5]),
                    Salaire_Demande = int.Parse(line[6]),
                    Preavis = int.Parse(line[7]),
                    Email = line[8],
                    Tel = line[9],
                    DateTestTechnique = Convert.ToDateTime(line[10]),
                    IdEtudes = NiveauxEtudes.Where(_ => _.INTITULE == line[3]).FirstOrDefault() == null ? -1 : NiveauxEtudes.Where(_ => _.INTITULE == line[3]).FirstOrDefault().ID_ETUDE,
                    IdExp = NiveauxExperience.Where(_ => _.INTITULE == line[4]).FirstOrDefault() == null ? -1 : NiveauxExperience.Where(_ => _.INTITULE == line[3]).FirstOrDefault().ID_EXPERIENCE
                };
                ListCandidatsCsv.Add(candidat);
                i++;

            }
            ObservableCollection<NIVEAU_ETUDE> etudes = NiveauxEtudes;
            ObservableCollection<NIVEAU_EXPERIENCE> exp = NiveauxExperience;
            etudes.RemoveAt(0);
            exp.RemoveAt(0);
            CSVCandidatView CSVCandidat = new CSVCandidatView(ListCandidatsCsv, etudes, exp);
            CSVCandidat.Show();



        }

        //Cette methode permet d'extraire des lignes à partir d'un fichier CSV 
        public void readXLSXdata(Stream File)
        {
            var _ms = new MemoryStream();
            CopyStream(File, _ms);
            var temp = System.IO.Path.GetTempPath(); // Get %TEMP% path
            var file = Path.GetFileNameWithoutExtension(string.Format("{0:N}.tmp", Guid.NewGuid())); // Get random file name without extension
            var path = Path.Combine(temp, file + ".xlsx"); // Get random file path

            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                // Write content of your memory stream into file stream
                _ms.WriteTo(fs);
            }

            // Open Workbook
            // excel.Workbooks.Open(path, ReadOnly: true);
            dynamic excelApp = AutomationFactory.CreateObject("Excel.Application");
            dynamic workbook = excelApp.Workbooks.Open(path);
            dynamic objActiveWorkSheet = workbook.ActiveSheet;
            dynamic objCell_1, objCell_2;

            //Iterate through Cells
            for (int row = 2; row <= objActiveWorkSheet.Rows.Count; ++row)
            {
                if (objActiveWorkSheet.Cells[row, 1].Value != null)
                {
                    //validation et mapping des données  
                    MessageBox.Show("test");


                }
                else
                {
                    break;
                }
            }
            
        }
        #endregion

    }
}
